package hu.elte.inf.holiuml.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import hu.elte.inf.holiuml.model.Attribute;
import hu.elte.inf.holiuml.model.ClassNode;
import hu.elte.inf.holiuml.model.Operation;
import hu.elte.inf.holiuml.model.UMLClass;


public class RepositoryDialog extends OptionsDialog{

	private JPanel propPanel;
	JComboBox nameCombo;
	JCheckBox showOpCheckBox;
	JCheckBox showAttrCheckBox;
	HoliUML parent;
	ClassNode classNode;
	Vector<Attribute> attributes = new Vector<Attribute>();
	Vector<Operation> operations = new Vector<Operation>();
	
	String ClassName;
	
	public RepositoryDialog(HoliUML parent, String title) 
	{
		super(parent, "Repository of Classes");
		this.parent = parent;
		createPropPanel();
		fillPanels();
		setSize(new Dimension(450,200));
		setModalityType(ModalityType.APPLICATION_MODAL);
		setVisible(true);
	}

	private void createPropPanel(){
		propPanel = new JPanel(new GridLayout(5,2));
		JLabel nameLabel = new JLabel("Name of the class:");
		
		//todo add existing names
		
		nameCombo = new JComboBox();
		nameCombo.setEditable(true);
		fillComboBox();
		
		nameCombo.addActionListener(
		 new ActionListener() {
		  public void actionPerformed(ActionEvent e) {
			LoadAttributes(nameCombo.getSelectedItem().toString());			
		  }
		 }
		);
		
		JLabel attrLabel = new JLabel("Attributes of the class:");
		JButton attrButton = new JButton("Edit attributes");
		attrButton.addActionListener(editAttributeAction);
		JLabel operationLabel = new JLabel("Methods of the class:");
		JButton operationButton = new JButton("Edit operation");
		operationButton.addActionListener(editOperationAction);
		
		JLabel showOpLabel = new JLabel("Show opeartions of the class?");
		showOpCheckBox = new JCheckBox("",true);
		JLabel showAttrLabel = new JLabel("Show attributes of the class?");
		showAttrCheckBox = new JCheckBox("",true);
		//adding to the panel
		
		
		
		
		propPanel.add(nameLabel);
		propPanel.add(nameCombo);
		propPanel.add(attrLabel);
		propPanel.add(attrButton);
		propPanel.add(operationLabel);
		propPanel.add(operationButton);
		propPanel.add(showAttrLabel);
		propPanel.add(showAttrCheckBox);
		propPanel.add(showOpLabel);
		propPanel.add(showOpCheckBox);
		
	}
	private void fillPanels(){
		getContentPane().setLayout(new BorderLayout());
		getContentPane().add("North", propPanel);
		getContentPane().add("South", buttonPanel);
	}
	private ActionListener editAttributeAction = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			ClassAttributeOptionsDialog attrDialog;
				 attrDialog = new ClassAttributeOptionsDialog(parent, "Edit attributes", attributes);
			if (attrDialog.getButtonCode() == OptionsDialog.OK) {
				attributes = attrDialog.getAttributes();
			}
		}
	};
	
	private ActionListener editOperationAction = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			ClassOperationOptionsDialog operationDialog;
			if(classNode == null){
				 operationDialog = new ClassOperationOptionsDialog(parent, "Edit operations", operations);
			}else{
				operationDialog = new ClassOperationOptionsDialog(parent, "Edit operations", classNode.getUMLClass().getOperations());
			}
			if (operationDialog.getButtonCode() == OptionsDialog.OK) {
				operations = operationDialog.getOperations();
			}
		}
	};
	
	public ClassNode createData(){
		UMLClass umlClass = new UMLClass();
		super.parent.getDocument().getModel().addClass(umlClass);
		
		umlClass.setName(ClassName);
		
		//nameCombo
		umlClass.setAttribute(attributes);
		umlClass.setOperation(operations);
		classNode = new ClassNode();
		classNode.setVisibleAttributes(showAttrCheckBox.isSelected());
		classNode.setVisibleOperations(showOpCheckBox.isSelected());
		classNode.setUMLClass(umlClass);
		
		return classNode;
	}
	
	public void modifyData(ClassNode classNode){
		classNode.getUMLClass().setName(nameCombo.getSelectedItem().toString());
		classNode.getUMLClass().setAttribute(attributes);
		classNode.getUMLClass().setOperation(operations);
	}
	
	protected boolean processOK(){
		if(ClassName.toString().replaceAll(" ", "").equals("")){
			JOptionPane.showMessageDialog(parent, "Please fill the class name!", "Error!", JOptionPane.WARNING_MESSAGE);
			return false;
		}
		return true;
	}
	protected void processCancel(){}
	
	/*
	 * Description: This function is used for fill the comboBox with name of the used objects.
	 * 
	 * The problem is to the comboBox can not give back the index of the selected item (just the first appearance of
	 * the object). It means that if somebody use two objects whit same name (for example: human) and the user selected
	 * the second object, the comboBox is able to give back the position of the first object.
	 * 
	 * This is the reason that I use the concatenation of the object name and index of object.
	 * 
	 */
	
	private void fillComboBox()
	{
		HashMap<String, Integer> counter = new HashMap<String, Integer>();
		counter.clear();
		for (int i=0; i< parent.getDocument().getModel().getUMLClass().size(); i++)
		{
			
			if (counter.containsKey(parent.getDocument().getModel().getUMLClass().elementAt(i).getName()))
			{
				int count = (Integer)counter.get(parent.getDocument().getModel().getUMLClass().elementAt(i).getName()) +1;
				counter.put(parent.getDocument().getModel().getUMLClass().elementAt(i).getName(), count);
			}
			else
			{
				counter.put(parent.getDocument().getModel().getUMLClass().elementAt(i).getName(), 1);
			}
			nameCombo.addItem(parent.getDocument().getModel().getUMLClass().elementAt(i).getName() + "_" + (Integer)counter.get(parent.getDocument().getModel().getUMLClass().elementAt(i).getName()) );
		}
		if (nameCombo.getItemCount() != 0)
		{
			LoadAttributes(nameCombo.getItemAt(0).toString());
		}
	}
	
	private int parser(String selectedString)
	{
		int line = selectedString.lastIndexOf('_');
		String firstPart = selectedString.substring(0, line);
		System.out.print("A class neve: " + firstPart);
		int numb = Integer.valueOf(selectedString.substring(line+1));
		ClassName = firstPart;
		return numb;
	}
	
	private void LoadAttributes(String selectedName)
	{
		int number = parser(selectedName);
		int j = 1;
		
		attributes.clear();
		operations.clear();
		
		System.out.print(ClassName + "_" + number);
		for (int i=0; i< parent.getDocument().getModel().getUMLClass().size(); i++)
		{
			if (parent.getDocument().getModel().getUMLClass().elementAt(i).getName().equalsIgnoreCase(ClassName))
			{
				System.out.print("KULSO");
				if (j == number)
				{
					System.out.print("ITT");
					for(int k = 0; k < parent.getDocument().getModel().getUMLClass().elementAt(i).getAttributes().size(); k++){
						attributes.add(new Attribute(parent.getDocument().getModel().getUMLClass().elementAt(i).getAttribute(k)));
					}
					for(int k = 0; k < parent.getDocument().getModel().getUMLClass().elementAt(i).getOperations().size(); k++){
						operations.add(new Operation(parent.getDocument().getModel().getUMLClass().elementAt(i).getOperationAt(k)));
					}
				}
				else
				{
					j++;
				}
			}
				
		}
	}
}
